package exams.concurrent;

import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

public class ForkJoinSumCalculator {

    public static void main(String[] args) {
        int[] array = new int[1000000]; // 创建一个包含100万个元素的数组
        Random random = new Random();
        for (int i = 0; i < array.length; i++) {
            array[i] = random.nextInt(100); // 随机生成数组元素的值
        }
        ForkJoinPool pool = new ForkJoinPool(); // 创建ForkJoinPool对象（默认使用处理器的核心数作为线程池大小）
        ArraySumTask task = new ArraySumTask(array); // 创建求和任务对象并传入数组作为参数（这里也可以传入数组的一部分作为参数来实现更细粒度的拆分）
        Long sum = pool.invoke(task); // 提交任务并等待处理完成（也可以使用submit方法提交任务并获取一个Future对象来异步获取结果）
        System.out.println("Sum: " + sum); // 输出结果（这里应该输出数组中所有元素的和）
        pool.shutdown(); // 关闭ForkJoinPool（释放资源）
    }

    static class ArraySumTask extends RecursiveTask<Long> {
        private static final int THRESHOLD = 1000; // 阈值，当数组长度小于等于该值时，采用普通方式求和
        private final int[] array;
        private final int low, high;

        public ArraySumTask(int[] array) {
            this(array, 0, array.length);
        }

        private ArraySumTask(int[] array, int low, int high) {
            this.array = array;
            this.low = low;
            this.high = high;
        }

        @Override
        protected Long compute() {
            if (high - low <= THRESHOLD) {
                // 数组长度小于等于阈值，采用普通方式求和
                long sum = 0;
                for (int i = low; i < high; i++) {
                    sum += array[i];
                }
                return sum;
            } else {
                // 数组长度大于阈值，拆分任务并递归处理
                int mid = low + (high - low) / 2;
                ArraySumTask leftTask = new ArraySumTask(array, low, mid);
                ArraySumTask rightTask = new ArraySumTask(array, mid, high);
                leftTask.fork(); // 拆分左半部分任务并异步执行
                rightTask.fork(); // 拆分右半部分任务并异步执行
                return leftTask.join() + rightTask.join(); // 等待左右两部分任务处理完成并合并结果
            }
        }
    }

}
